package moe.bogos.douro.api.client.entity.render;

import com.mojang.blaze3d.matrix.MatrixStack;
import moe.bogos.douro.api.common.entity.SoulRingDropEntity;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererManager;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.math.vector.Vector4f;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.ARBVertexBufferObject;
import org.lwjgl.opengl.GL11;

import java.nio.FloatBuffer;

public class SoulRingDropRenderer extends EntityRenderer<SoulRingDropEntity>
{
    private static final float radius = 0.41f;
    private static final float radius2 = 0.35f;
    private static final float height = 0.07f;
    private static final int sides = 64;
    private static final float[] vexArray = new float[(sides + 1) * 2 * 4 * 3];
    //private static final float[] vexArray2 = new float[360 * 2 * 3];
    
    //private int i = 0;
    //private int j = 0;
    
    static
    {
        float angle = 360f / (float) sides;
        for (int i = 0; i <= sides; i++)
        {
            vexArray[i * 6] = (float) Math.cos(angle * i / 180f * Math.PI) * radius;
            vexArray[i * 6 + 2] = (float) Math.sin(angle * i / 180f * Math.PI) * radius;
            vexArray[i * 6 + 1] = height / 2f;
            
            vexArray[i * 6 + 3] = (float) Math.cos(angle * i / 180f * Math.PI) * radius2;
            vexArray[i * 6 + 5] = (float) Math.sin(angle * i / 180f * Math.PI) * radius2;
            vexArray[i * 6 + 4] = height / 2f;
        }
        
        for (int i = 0; i <= sides; i++)
        {
            vexArray[6 * (sides + 1) + i * 6] = (float) Math.cos(angle * i / 180f * Math.PI) * radius;
            vexArray[6 * (sides + 1) + i * 6 + 2] = (float) Math.sin(angle * i / 180f * Math.PI) * radius;
            vexArray[6 * (sides + 1) + i * 6 + 1] = height / 2f;
            
            vexArray[6 * (sides + 1) + i * 6 + 3] = (float) Math.cos(angle * i / 180f * Math.PI) * radius;
            vexArray[6 * (sides + 1) + i * 6 + 5] = (float) Math.sin(angle * i / 180f * Math.PI) * radius;
            vexArray[6 * (sides + 1) + i * 6 + 4] = -height / 2f;
        }
        
        for (int i = 0; i <= sides; i++)
        {
            vexArray[12 * (sides + 1) + i * 6] = (float) Math.cos(angle * i / 180f * Math.PI) * radius2;
            vexArray[12 * (sides + 1) + i * 6 + 2] = (float) Math.sin(angle * i / 180f * Math.PI) * radius2;
            vexArray[12 * (sides + 1) + i * 6 + 1] = height / 2f;
            
            vexArray[12 * (sides + 1) + i * 6 + 3] = (float) Math.cos(angle * i / 180f * Math.PI) * radius2;
            vexArray[12 * (sides + 1) + i * 6 + 5] = (float) Math.sin(angle * i / 180f * Math.PI) * radius2;
            vexArray[12 * (sides + 1) + i * 6 + 4] = -height / 2f;
        }
        
        for (int i = 0; i <= sides; i++)
        {
            vexArray[18 * (sides + 1) + i * 6] = (float) Math.cos(angle * i / 180f * Math.PI) * radius;
            vexArray[18 * (sides + 1) + i * 6 + 2] = (float) Math.sin(angle * i / 180f * Math.PI) * radius;
            vexArray[18 * (sides + 1) + i * 6 + 1] = -height / 2f;
            
            vexArray[18 * (sides + 1) + i * 6 + 3] = (float) Math.cos(angle * i / 180f * Math.PI) * radius2;
            vexArray[18 * (sides + 1) + i * 6 + 5] = (float) Math.sin(angle * i / 180f * Math.PI) * radius2;
            vexArray[18 * (sides + 1) + i * 6 + 4] = -height / 2f;
        }
        
        /*float radius3 = (radius + radius2) / 2;
        float o = (radius + radius2) / 2;
        
        for (int i = 0; i < 360; i++)
        {
            vexArray2[i * 3] = -o + (float) Math.cos((float) i / 180f * Math.PI) * radius3;
            vexArray2[i * 3 + 1] = (float) Math.sin((float) i / 180f * Math.PI) * radius3;
            vexArray2[i * 3 + 2] = 0f;
        }
        
        for (int i = 0; i < 360; i++)
        {
            vexArray2[360 * 3 + i * 3] = o - (float) Math.cos((float) i / 180f * Math.PI) * radius3;
            vexArray2[360 * 3 + i * 3 + 1] = (float) Math.sin((float) i / 180f * Math.PI) * radius3;
            vexArray2[360 * 3 + i * 3 + 2] = 0f;
        }
        
        for (int i = 0; i < 720; i++)
            System.out.println(vexArray2[i * 3] + " " + vexArray2[i * 3 + 1] + " " + vexArray2[i * 3 + 2]);
            */
    }
    
    public SoulRingDropRenderer(EntityRendererManager entityRenderDispatcher)
    {
        super(entityRenderDispatcher);
    }

    @Override
    public void render(SoulRingDropEntity entity, float entityYaw, float partialTicks, MatrixStack matrixStack, IRenderTypeBuffer renderTypeBuffer, int packedLight)
    {
        GL11.glPushMatrix();
        
        GL11.glDisable(GL11.GL_TEXTURE_2D);
        GL11.glDisable(GL11.GL_CULL_FACE);
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        GL11.glDepthFunc(GL11.GL_LEQUAL);
        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
        //GL11.glDisable(GL11.GL_LIGHTING);
        GL11.glEnable(GL11.GL_BLEND);
        //GL11.glEnable(GL11.GL_LINE_SMOOTH);
        
        //GL11.glHint(GL11.GL_LINE_SMOOTH_HINT, GL11.GL_NICEST);
        
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
        
        float caYaw = entityRenderDispatcher.camera.getYRot();
        float caPitch = entityRenderDispatcher.camera.getXRot();
        GL11.glRotatef(caPitch, 1.0f, 0.0f, 0.0f);
        GL11.glRotatef(caYaw + 180f, 0.0f, 1.0f, 0.0f);

        Vector3d caVec = entityRenderDispatcher.camera.getPosition();
        GL11.glTranslated(-caVec.x(), -caVec.y(), -caVec.z());
        
        Vector3d pos = entity.getPosition(partialTicks);
        GL11.glTranslated(pos.x, pos.y, pos.z);
        GL11.glRotatef(entity.yRot + 180f, 0.0f, 1.0f, 0.0f);
        GL11.glRotatef(-entity.xRot, 1.0f, 0.0f, 0.0f);
        
        Vector4f c = entity.getColor();
        GL11.glColor4d(c.x(), c.y(), c.z(), c.w());
        
        
        FloatBuffer vexBuffer = BufferUtils.createFloatBuffer((sides + 1) * 2 * 4 * 3);
        vexBuffer.put(vexArray);
        vexBuffer.flip();

        /*FloatBuffer colorBuffer = BufferUtils.createFloatBuffer((sides + 1) * 2 * 4 * 4);
        for (int i = 0; i < (sides + 1) * 2 * 4; i++)
            colorBuffer.put(238f / 255f).put(199f / 255f).put(16f / 255f).put(0.7f);
        colorBuffer.flip();*/
        
        /*FloatBuffer vexBuffer2 = BufferUtils.createFloatBuffer(270);
        for (int j = 0; j < 270; j++) vexBuffer2.put(vexArray2[(j + i) % (360 * 2 * 3)]);
        vexBuffer2.flip();
        
        FloatBuffer colorBuffer2 = BufferUtils.createFloatBuffer(270 * 4);
        for (int i = 0; i < 270; i++)
            colorBuffer2.put(238f / 255f).put(199f / 255f).put(16f / 255f).put(1.0f - ((float) i) / 270f);
        colorBuffer2.flip();*/
        
        GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
        //GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
        
        int vId = ARBVertexBufferObject.glGenBuffersARB();
        //int cId = ARBBufferObject.glGenBuffersARB();
        
        ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vId);
        ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vexBuffer, ARBVertexBufferObject.GL_STATIC_DRAW_ARB);
        GL11.glVertexPointer(3, GL11.GL_FLOAT, 3 << 2, 0L);

        /*ARBBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, cId);
        ARBBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, colorBuffer, ARBVertexBufferObject.GL_STATIC_DRAW_ARB);
        GL11.glColorPointer(4, GL11.GL_FLOAT, 4 << 2, 0L);*/
        
        GL11.glDrawArrays(GL11.GL_QUAD_STRIP, 0, (sides + 1) * 2);
        GL11.glDrawArrays(GL11.GL_QUAD_STRIP, (sides + 1) * 2, (sides + 1) * 2);
        GL11.glDrawArrays(GL11.GL_QUAD_STRIP, (sides + 1) * 4, (sides + 1) * 2);
        GL11.glDrawArrays(GL11.GL_QUAD_STRIP, (sides + 1) * 6, (sides + 1) * 2);
        
        /*vId = ARBBufferObject.glGenBuffersARB();
        cId = ARBBufferObject.glGenBuffersARB();
        
        ARBBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vId);
        ARBBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vexBuffer2, ARBVertexBufferObject.GL_STATIC_DRAW_ARB);
        GL11.glVertexPointer(3, GL11.GL_FLOAT, 3 << 2, 0L);
        
        ARBBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, cId);
        ARBBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, colorBuffer2, ARBVertexBufferObject.GL_STATIC_DRAW_ARB);
        GL11.glColorPointer(4, GL11.GL_FLOAT, 4 << 2, 0L);
        
        GL11.glDrawArrays(GL11.GL_LINE_STRIP, 0, 270);*/
        
        ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, 0);
        
        GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
        //GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
        
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glEnable(GL11.GL_CULL_FACE);
        GL11.glDisable(GL11.GL_DEPTH_TEST);
        //GL11.glEnable(GL11.GL_LIGHTING);
        GL11.glDisable(GL11.GL_BLEND);
        //GL11.glDisable(GL11.GL_LINE_SMOOTH);
        
        GL11.glPopMatrix();
        GL11.glColor4d(1.0, 1.0, 1.0, 1.0);
    }

    @Override
    public ResourceLocation getTextureLocation(SoulRingDropEntity entity)
    {
        return null;
    }
}
